using System;

namespace BiologicalResearch
{
    /// <summary>
    /// Represents an intelligent agent for biological research simulations
    /// </summary>
    public class BiologicalAgent
    {
        /// <summary>
        /// Unique identifier for the agent
        /// </summary>
        public string Id { get; private set; }

        /// <summary>
        /// Current energy level of the agent (0-100)
        /// </summary>
        public int EnergyLevel { get; private set; }

        /// <summary>
        /// Knowledge base of the agent
        /// </summary>
        public string[] KnowledgeBase { get; private set; }

        /// <summary>
        /// Creates a new biological research agent
        /// </summary>
        /// <param name="id">Agent identifier</param>
        public BiologicalAgent(string id)
        {
            Id = id;
            EnergyLevel = 100;
            KnowledgeBase = Array.Empty<string>();
        }

        /// <summary>
        /// Simulates the agent performing research
        /// </summary>
        /// <param name="researchTopic">Topic to research</param>
        /// <returns>Findings from the research</returns>
        /// <exception cref="ArgumentException">Thrown when researchTopic is null or empty</exception>
        public string PerformResearch(string researchTopic)
        {
            if (string.IsNullOrWhiteSpace(researchTopic))
            {
                throw new ArgumentException("Research topic cannot be empty", nameof(researchTopic));
            }

            if (EnergyLevel < ResearchEnergyCost)
            {
                return "Insufficient energy to perform research";
            }

            EnergyLevel -= ResearchEnergyCost;
            var findings = $"Preliminary findings on {researchTopic}: " +
                          $"Sample data suggests potential for further study.";
            
            KnowledgeBase.Add(findings);

            return findings;
        }

        /// <summary>
        /// Rests the agent to restore energy
        /// </summary>
        public void Rest()
        {
            EnergyLevel = (byte)Math.Min(100, EnergyLevel + RestEnergyGain);
        }

        /// <summary>
        /// Collaborates with another agent by sharing knowledge
        /// </summary>
        /// <param name="otherAgent">Agent to collaborate with</param>
        public void Collaborate(BiologicalAgent otherAgent)
        {
            if (otherAgent == null)
            {
                throw new ArgumentNullException(nameof(otherAgent));
            }

            if (EnergyLevel < ResearchEnergyCost)
            {
                return;
            }

            EnergyLevel -= ResearchEnergyCost;
            KnowledgeBase.AddRange(otherAgent.KnowledgeBase
                .Where(k => !KnowledgeBase.Contains(k)));
        }
    }
}